package com.yinlei.appserver

import android.util.Log
import java.io.IOException
import java.net.InetSocketAddress
import java.net.ServerSocket
import java.net.Socket
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.concurrent.thread

class SimpleHttpServer (var webConfig: WebConfiguration){

    private var threadPool: ExecutorService = Executors.newCachedThreadPool()
    private lateinit var socket: ServerSocket
    private var isEnable: Boolean = false
    private val resourceHandlers: MutableSet<IResourceUriHandler> = HashSet<IResourceUriHandler>()
    /**
     * 启动server异步
     */
    fun startAsync(){
        isEnable = true
        thread {
            doProcSync()
        }
    }


    /**
     * 停止服务器
     */
    fun stopAsync(){
        if (!isEnable){
            return
        }
        isEnable = false
        socket.close()
    }


    private fun doProcSync() {
        try{
            val socketAddr = InetSocketAddress(webConfig.port)
            socket = ServerSocket()
            socket.bind(socketAddr)
            while (isEnable){
                val remotePeer = socket.accept()
                threadPool.submit{
                    Log.d("yinlei","a remote peer accepted...${remotePeer.remoteSocketAddress}")
                    onAcceptRemotePeer(remotePeer)
                }
            }
        }catch (e: IOException){
            Log.e("yinlei",e.toString())
        }
    }


    fun registerResourceHandler(handler: IResourceUriHandler) {
        resourceHandlers.add(handler)
    }

    private fun onAcceptRemotePeer(remotePeer: Socket) {
        try {
            val httpContext = HttpContext()
            httpContext.setUnderlySocket(remotePeer)
//            remotePeer.getOutputStream().write("congrativation, connected successful!".toByteArray())
            val nis = remotePeer.getInputStream()
            var headerLine: String
            val resourceUrl = StreamToolkit.readLine(nis)?.split(" ")?.get(1)!! // 拿到请求的url
            Log.d("yinlei",resourceUrl)

            while (StreamToolkit.readLine(nis).also { headerLine = it!!} != null){
                if (headerLine == "\r\n"){
                    break
                }


                Log.d("yinlei",headerLine)

                val pair = headerLine.split(": ")
                if(pair.size > 1) {
                    httpContext.addRequestHeader(pair[0], pair[1])
                }
            }

            for (handler in resourceHandlers) {
                if (!handler.accept(resourceUrl)) {
                    continue
                }
                handler.handle(resourceUrl, httpContext)
            }
        } catch (e: IOException) {
            Log.e("yinlei",e.toString())
        }
    }

}